home *** CD-ROM | disk | FTP | other *** search
- /* PROGRAM R.Tutor */
- /* (a home-grown tutorial for writing applications using resources */
- /* Part 1 - starting up & shutting down the tools from a ToolStartup */
- /* list kept in a resource */
- /* Part 2 - add a menu bar that is kept in a resource */
- /* Part 3 - add the event loop so that the menus "come alive" and put up a */
- /* window that is defined in the resource fork */
- /* Part 3.2 - change "About" box from a simple beep into an Alert Window and */
- /* redo the Rez and MAKE file so that we can avoid re-compiling */
- /* the the parts that haven't changed and also to show off some */
- /* of Rez's special abilities such as including already compiled */
- /* resources from another file and appending Rez's output to an */
- /* already existing resource without wiping out the existing */
- /* resources... */
- /* Part 3.3 - tossed out the seperate Rez file that showed how to include */
- /* pre-compiled resources and the "-a" flag. If you want to know */
- /* how those are done, see Part 3.2's source. I also tossed the */
- /* controls out of the window and put some icons in the window. */
- /* Naturally, the icons are stored as resources. I've also */
- /* slipped in a special cursor that's kept as a resource also - */
- /* mainly to show people how to use the current definition of how */
- /* an rCursor should be defined (the bit map for an rCursor is */
- /* done differently from the bitmap for an rIcon). */
-
- #include <types.h>
- #include <INTMATH.h>
- #include <MEMORY.h>
- #include <MISCTOOL.h>
- #include <LOCATOR.h>
- #include <DESK.H>
- #include <QUICKDRAW.h>
- #include <EVENT.h>
- #include <CONTROL.h>
- #include <WINDOW.h>
- #include <MENU.h>
- #include <GSOS.h>
- #include <Resources.h>
- #include <QDAux.h> /* added for part 3.3 */
-
- #define kStartStopID 1L /* used when starting and shutting down tools */
-
- /*---------------------- Menus & Menu Bars ---------------------------*/
- #define kMenuBarID 1L /* resource ID of the menu bar itself */
-
- /* define all the menu id's */
- #define kAppleMenuID 1000 /* resource ID of the Apple menu */
- #define kFileMenuID 2000 /* resource ID of the File menu */
- #define kEditMenuID 3000 /* resource ID of the Edit menu */
-
- /* now, define the menu item id's */
- #define kAboutBoxID 1001 /* resource ID of the About Box menu item */
-
- #define kNewItemID 2001 /* resource ID of the New Item in File menu */
- #define kOpenItemID 2002 /* resource ID of the Open item in File menu */
- #define kCloseItemID 255 /* the "Close" item */
- #define kSaveItemID 2004 /* the "Save" item */
- #define kSaveAsItemID 2005 /* the "Save As..." item */
- #define kRevertItemID 2006 /* the "Revert to Saved" item */
- #define kPageItemID 2007 /* the "Page Setup..." item */
- #define kPrintItemID 2008 /* the "Print..." item */
- #define kQuitItemID 2009 /* the "Quit" item */
-
- #define kUndoItemID 250 /* the "Undo" item */
- #define kCutItemID 251 /* the "Cut" item */
- #define kCopyItemID 252 /* the "Copy" item */
- #define kPasteItemID 253 /* the "Paste" item */
- #define kClearItemID 254 /* the "Clear" item */
- #define kSelectItemID 3001 /* the "Select All" item */
- #define kShowClipItemID 3002 /* the "Show ClipBoard" item */
-
- /* define the resource ID's for all windows used by this app */
- #define myWindowID 2362L /* window's resource ID = 2362 */
-
- /* declare the constants for our TaskMaster event mask */
- #define kMyTaskMask 0x001FFFFFL /* this mask is for TaskMaster itself */
- #define kMyEventMask 0xFFFF /* this mask is passed to GetNextEvent */
-
- /* define the constants used for the cursors */
- #define rFirstCursor 1 /* added for part 3.3 */
-
- /* define the constant used to represent the first icon we're adding */
- /* added for part 3.3 */
- #define kFloorIcon 1 /* ID of the icon used as the "floor" */
-
- /* declare the global variable that we'll use with TaskMaster */
- WmTaskRec gMyEvent;
-
-
- /* declare all of the global variables that we'll be using */
- unsigned gMyMemID; /* holds the ID returned by MMStartup */
- Ref gToolListRef; /* list of tools used to start and stop the tools */
- Boolean gPunt; /* TRUE if it's time to quit the app */
- word gWhichCursor; /* used to tell which of four cursors to use */
- CursorHndl grCursorHndl; /* used to hold handle to rCursor */
-
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure is responsible for putting up the About box */
-
- #define kAboutStr 100L /* define the constant for the About box's string */
-
- do_show_about()
- {
- /* change the beep into an Alert Window - grab the Alert from a resource */
- word pickedButton;
- pickedButton = AlertWindow(0x0004, /* alert string is in resource fork */
- /* and is a "C" string */
- NULL, /* not used right now */
- kAboutStr); /* resource ID of Alert's string */
- }
-
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure is responsible for quitting the app */
-
- do_quit_app()
- {
- /* we actually just set the "quit" flag and let the real quitting happen */
- /* in the main event loop. Later, we would add code here to cope with */
- /* closing all open windows, saving their contents, etc. */
-
- gPunt = TRUE;
- }
-
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure is responsible for dealing with items picked */
- /* from the menus by the user */
-
- do_menu_events()
- {
-
- unsigned int pickedMenuID; /*ID of menu the user just picked an item from */
- unsigned int pickedItemID; /* ID of item the user just picked */
-
- /* the hi-word of wmTaskData is the menu ID */
- pickedMenuID = HiWord(gMyEvent.wmTaskData);
-
- /* the lo-word of wmTaskData is the item ID */
- pickedItemID = LoWord(gMyEvent.wmTaskData);
-
- switch(pickedItemID)
- {
- case kAboutBoxID : do_show_about(); /* show the About box */
- break;
- case kNewItemID : break; /* that's all for this item */
- case kOpenItemID : break; /* that's all for this item */
- case kCloseItemID : break; /* that's all for this item */
- case kSaveItemID : break; /* that's all for this item */
- case kSaveAsItemID : break; /* that's all for this item */
- case kRevertItemID : break; /* that's all for this item */
- case kPageItemID : break; /* that's all for this item */
- case kPrintItemID : break; /* that's all for this item */
- case kQuitItemID : do_quit_app(); /* sets gPunt to TRUE */
- break;
- case kUndoItemID : break; /* that's all for this item */
- case kCutItemID : break; /* that's all for this item */
- case kCopyItemID : break; /* that's all for this item */
- case kPasteItemID : break; /* that's all for this item */
- case kClearItemID : break; /* that's all for this item */
- case kSelectItemID : break; /* that's all for this item */
- case kShowClipItemID : break; /* that's all for this item */
-
- default: ; /* always have a default action in case something goes wrong */
-
- } /* end of the "switch" statement */
-
- /* Turn off the highlighting on the menu the user picked the item from. */
- /* Then return to the main event loop to see what we'll do next. */
- HiliteMenu(FALSE,pickedMenuID);
- }
-
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure installs the menu bar from a resource */
-
- do_make_menus()
- {
- MenuBarRecHndl my_mbar_hndl;
- word menu_bar_height;
- {
-
- /* the next three calls are ALL required to bring the menu bar in from */
- /* the resource fork AND make it the current system menu bar. For */
- /* details, see the IIGS Toolbox Reference, under NewMenuBar2 */
- my_mbar_hndl = NewMenuBar2(refIsResource, kMenuBarID, nil);
- SetSysBar(my_mbar_hndl);
- SetMenuBar(nil);
-
- /* now, add NDA's, adjust the sizes of the menus, and draw the menu bar */
- /* kAppleMenuID used to be defined as a long and had to be cast to a */
- /* word here. It's been redefined to be only a word in size, so the */
- /* casting is no longer needed. */
- FixAppleMenu(kAppleMenuID); /* adds NDA's */
- menu_bar_height = FixMenuBar(); /* adjust the sizes */
- DrawMenuBar(); /* draw the new menu bar and enjoy! */
- }
- }
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure is responsible for starting the tools (using the */
- /* list in a resource) if the SartupTools call fails, then gPunt will */
- /* contain "TRUE", so we can abort the app the global variable for this */
- /* app's memory id is acquired here as well. */
-
- do_init_rom()
- {
- gMyMemID = _ownerid; /* find out our memory id & save it for later */
-
- /* crank 'em up! - make sure that kStartStopID is defined as a long!!! */
- gToolListRef = StartUpTools(gMyMemID,refIsResource,kStartStopID);
-
- if (_toolErr == noError)
- { /* there was no error, so the app can continue starting up */
- gPunt = FALSE;
- }
- else
- { /* something went wrong, so set gPunt to indicate the failure */
- gPunt = TRUE;
- }
-
- gWhichCursor = rFirstCursor; /* we're going to use a custom cursor */
- }
-
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure draws the contents of the window that we created */
- /* from the template in the resource fork. Any time the window's content */
- /* region needs to be redrawn, this routine gets called. Put a SysBeep() */
- /* call in here if you want to investigate when this routine gets called. */
- /* That will cause a beep every time this routine gets called... */
-
- drawMyContents()
- {
- /* declare a couple of local variables that we'll need */
- /* handle to an icon loaded from the resource fork */
- QDIconRecordHndl my_RHndl;
- long my_icon_id; /* resource ID of icon to be used */
-
-
- /* initialize my_icon_id to use the "floor" icon */
- my_icon_id = kFloorIcon;
-
- /* There are two ways to draw an icon on the screen. The first one */
- /* is to make a control that includes an icon in it and use */
- /* "DrawControl" to draw it for us. Since we just want to decorate */
- /* our screen and don't really want to have controls, we're going to */
- /* use the second way. The second way is to use the toolbox call */
- /* "DrawIcon" to draw it. DrawIcon needs a pointer to the icon */
- /* that's going to be drawn. No problem - LoadResource gives us a */
- /* handle to the icon, so we just dereference the handle and pass */
- /* the resulting pointer to DrawIcon... */
-
- /* first we load the icon using the "LoadResource" toolbox call */
- /* LoadResource returns a "handle" so we have to type cast it to */
- /* QDIconRecordHndl */
- my_RHndl = (QDIconRecordHndl) LoadResource(rIcon, my_icon_id);
-
- /* Lock the handle so it can't move while we're drawing */
- HLock(my_RHndl);
-
- /* next, we draw it at a fixed location using the "DrawIcon" toolbox call */
- /* horz = 30, vert = 60 */
- DrawIcon(*my_RHndl, 0, 30, 60);
-
- /* Let's draw it in a bunch of different places. The icon is six */
- /* pixels wide, but we're using dithered pixels on the 640 screen, */
- /* so we have to move over 12 pixels to prevent the icons from */
- /* overlapping. */
- DrawIcon(*my_RHndl, 0, 42, 60);
- DrawIcon(*my_RHndl, 0, 54, 60);
- DrawIcon(*my_RHndl, 0, 66, 60);
- DrawIcon(*my_RHndl, 0, 78, 60);
- DrawIcon(*my_RHndl, 0, 90, 60);
- DrawIcon(*my_RHndl, 0,102, 60);
- DrawIcon(*my_RHndl, 0,114, 60);
- DrawIcon(*my_RHndl, 0,126, 60);
- DrawIcon(*my_RHndl, 0,138, 60);
- DrawIcon(*my_RHndl, 0, 78, 76); /* put this one away from the others */
-
- /* Unlock the handle - NEVER forget to unlock a handle you locked! */
- HUnlock(my_RHndl);
- }
-
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure creates a window using a template that is kept */
- /* in the application's resource fork */
-
- do_make_window()
- {
- /* since we only have one window and it can't be closed, we won't */
- /* bother to keep the grafPortPtr in a global. We can always get it */
- /* back by calling FrontWindow(). Later, when we add multiple windows, */
- /* we'll want a better way to keep track of the grafPortPtr to each */
- /* window, but for now I'd like to keep it simple. */
-
- GrafPortPtr myWndwPtr;
-
- myWndwPtr = NewWindow2(NIL, /* use "default" title string from param block */
- NIL, /* use "default" refCon from param block */
- drawMyContents, /* procedure that draws contents */
- NIL, /* use std def proc for this window */
- refIsResource, /* template is in a resource */
- myWindowID, /* resource ID of our window */
- rWindParam1); /* template is of param type 1 */
-
- SetPort(myWndwPtr); /* set the Graf Port to the newly created window's */
- }
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure is the main event loop. It runs until gPunt is */
- /* set to TRUE by the user picking "Quit" from the File menu. */
-
- do_main_event()
- {
- word myTaskCode; /* used to hold the task codes returned by Task Master */
-
-
- /* tell Task Master which events it can do */
- /* we're lazy, so let it handle everything possible! */
- gMyEvent.wmTaskMask = kMyTaskMask;
-
- while(!gPunt) /* keep calling Task Master until "Quit" has been selected */
- {
- myTaskCode = TaskMaster(kMyEventMask, &gMyEvent);
- switch(myTaskCode)
- {
- case wInGoAway:
- break;
- case wInSpecial:
- case wInMenuBar:
- do_menu_events();
- break;
- default:
- break; /* always have a default */
- } /* end of the switch statement */
- } /* end of the "while" */
- } /* end of do_main_event */
-
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure is the main application itself. */
- /* don't forget to add the code that will check the message center to see if */
- /* this app was launched by clicking on its icon or by clicking on a data */
- /* file created by this app. If the data file was clicked on, then grab its */
- /* name out of the message center and open it instead of opening the */
- /* untitled window. */
-
- main()
- {
- do_init_rom(); /* get my memory id, start the tools, & set gPunt */
- if (gPunt == FALSE)
- {
- do_make_menus(); /* insert the menu bar */
- do_make_window(); /* create a new window from the resource fork */
- InitCursor(); /* this changes the cursor to the "normal" one. */
- /* It was left as a watch cursor when the tools */
- /* were started up. */
-
- /* Set the cursor to a custom one that's in the resource fork. */
- /* To do this, we have to load it, lock the handle, call SetCursor */
- /* and then unlock the handle. */
- grCursorHndl = (CursorHndl) LoadResource(rCursor, (long) gWhichCursor);
- HLock(grCursorHndl);
- SetCursor(*grCursorHndl);
- HUnlock(grCursorHndl);
-
- do_main_event();
- }
- ShutDownTools(refIsHandle,gToolListRef); /* shut down the tools and quit */
- } /* end of main program */
-